Skip to content

[US-16.2 / OBT-253] Exclude platform admins from the project Grant User picker - #37

Open
levigtri wants to merge 3 commits into
mainfrom
levigft/obt-253-us-162-exclude-platform-admins-from-the-project-grant-user
Open

[US-16.2 / OBT-253] Exclude platform admins from the project Grant User picker#37
levigtri wants to merge 3 commits into
mainfrom
levigft/obt-253-us-162-exclude-platform-admins-from-the-project-grant-user

Conversation

@levigtri

@levigtri levigtri commented Jul 13, 2026

Copy link
Copy Markdown
Member

[US-16.2 / OBT-253] Exclude platform admins from the project Grant User picker

Summary

Platform Admin accounts must not be offered when granting access to a project — they already manage every project implicitly, so they can't be added as a member or given a project role. The "Grant User Access" dialog on a project's Access tab uses UserSearchPicker, which previously filtered results only by excludeIds (users already granted). This change teaches the picker to drop platform admins from its results, and wires that on in the project Access tab. The user-search response (UserListResponse) already carries is_platform_admin, so no new endpoint is needed. The already-granted members table is unaffected because the backend (US-16.1, shemaobt/tripod-api#…) now excludes admins from the listing. As defense in depth, the grant handler also surfaces the backend's 400 rejection with a clear toast, in case an admin is reached some other way.

Changes

  1. src/components/common/UserSearchPicker.tsx — new optional excludePlatformAdmins prop. When set, search results with is_platform_admin are filtered out (alongside the existing excludeIds filter, now folded into a single results.filter). The empty-results message is generalized to "All matching users are already added or unavailable" so it reads correctly whether matches were dropped for being already-added or for being admins.
  2. src/components/pages/ProjectAccessTab.tsx — passes excludePlatformAdmins to the Grant User picker, and adds a 400 branch to handleGrantUser that toasts "Platform admins can't be added to a project" (defense in depth; the picker already prevents selecting one).

Type of Change

  • New feature (non-breaking change which adds functionality)
  • Bug fix (platform admins no longer selectable for project access)
  • Breaking change
  • Refactor / chore

Testing

  1. npm run typecheck, npm run lint (0 errors; only the pre-existing ProjectsPage warning) and npm run build pass.
  2. With the backend branch of US-16.1 running locally, on a project's Access tab → Grant User:
    1. Search for a platform admin by email or name — the admin never appears in the results dropdown.
    2. When the only matches are admins (or already-granted users), the dropdown shows the "already added or unavailable" message instead of an admin row.
    3. Non-admin users still appear, can be selected, and are granted as before.
    4. Defense in depth: if the backend rejects a grant with 400, the dialog shows the "Platform admins can't be added to a project" toast.

Summary by CodeRabbit

  • New Features

    • Platform administrators are now excluded when selecting users for project access.
    • Added clearer guidance when no eligible users are available to add.
  • Bug Fixes

    • Improved error handling when attempting to grant project access to a platform administrator.

levigtri added 2 commits July 13, 2026 15:26
Optional prop to drop platform admins from the search results, folded into
the existing excludeIds filter. Generalize the empty-results message so it
reads correctly whether matches were dropped for being already-added or for
being admins.
Platform admins already manage every project, so they can't be added as
members. Enable excludePlatformAdmins on the Grant User picker, and surface
the backend's 400 rejection with a clear toast as defense in depth.
@linear-code

linear-code Bot commented Jul 13, 2026

Copy link
Copy Markdown

OBT-253

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

UserSearchPicker can exclude platform administrators and correctly determine its empty state from API results. ProjectAccessTab enables this filtering in the grant-access dialog and displays a dedicated message for HTTP 400 responses.

Changes

Platform Admin Access

Layer / File(s) Summary
User picker filtering
src/components/common/UserSearchPicker.tsx
Adds the excludePlatformAdmins prop, filters platform admins from results when enabled, and bases empty-state text on API results.
Project access integration
src/components/pages/ProjectAccessTab.tsx
Excludes platform admins from the grant-access picker and displays a dedicated error for HTTP 400 responses.

Suggested reviewers: joaocarvoli

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: excluding platform admins from the project Grant User picker.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch levigft/obt-253-us-162-exclude-platform-admins-from-the-project-grant-user

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/components/common/UserSearchPicker.tsx (1)

73-77: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add regression coverage for the filtering contract.

Test mixed results, all-platform-admin results, and existing-user exclusion so the new empty-state behavior cannot regress.

Also applies to: 136-138

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/common/UserSearchPicker.tsx` around lines 73 - 77, Add
regression tests for the filtering logic in UserSearchPicker, covering mixed
results, results consisting entirely of platform admins, and exclusion of IDs
already present in excludeIds. Assert that each scenario produces the expected
filtered results and empty state, preserving the contract implemented by the
results.filter predicate.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/components/common/UserSearchPicker.tsx`:
- Around line 73-77: Add regression tests for the filtering logic in
UserSearchPicker, covering mixed results, results consisting entirely of
platform admins, and exclusion of IDs already present in excludeIds. Assert that
each scenario produces the expected filtered results and empty state, preserving
the contract implemented by the results.filter predicate.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: QUIET

Plan: Pro Plus

Run ID: d5712728-0027-4622-a3bb-ba257f495851

📥 Commits

Reviewing files that changed from the base of the PR and between 130fc4a and d932479.

📒 Files selected for processing (2)
  • src/components/common/UserSearchPicker.tsx
  • src/components/pages/ProjectAccessTab.tsx

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant